CloudFormationでFargateのタスクのスケジューリングを構築する #Fargate
こんにちは、コカコーラ大好きカジです。
VPC構築済みの環境や、同じVPC内に複数のタスクのスケジューリングのFargateを複数構築するときに使えるCloudFormationテンプレートを作成してみました。 Fargateに関連するCloudwatch Logsの設定も含まれています。 また、自分が使いたいFargateのサンプルが見つからなかったので作成しました。 どなたかのお役に立てれば光栄です。
前提条件
- VPC、サブネット、ECS Task用のSecurity Groupが構築済み
- Fargateを配置するサブネットは、NATゲートウェイ経由でインターネット通信またはPrivate LinkでECRへ通信可能
- ECRリポジトリが構築済みで、DockerイメージをPushしておくこと、無い場合はこちらのブロクでDockerイメージの作成とECRを構築してください。
スケジューリングのFargateの構築
文末のCloudFormationテンプレートでCreate Stackしてください。
Crate Stack時に、VPC、Subnet、Security Group、ECRを指定するようにしています。そのほかはそのままでOKです。
途中、ECS用のIAM Roleを作成するためIAMの許可にチェックを入れます。
Create Stackが正常に終わると以下のようになります。正常にできない場合は、ネットワーク構成や指定しているVPC、サブネットに誤りがないか確認しましょう。
あと、テスト起動するよう、スケジュールを1dayから、cronの時間指定へ変更して動作させてみます。
起動すると以下の表示になります。
コンテナ側のIPアドレスは以下の部分で確認します。
起動しているコンテナは、nginxのコンテナなので、外部からcurlコマンドでコンテナへアクセスすると、以下のようにnginxが表示されます。
$ curl -v http://10.1.21.66 * Rebuilt URL to: http://10.1.21.66/ * Trying 10.1.21.66... * TCP_NODELAY set * Connected to 10.1.21.66 (10.1.21.66) port 80 (#0) > GET / HTTP/1.1 > Host: 10.1.21.66 > User-Agent: curl/7.61.1 > Accept: */* > < HTTP/1.1 200 OK < Server: nginx/1.15.8 < Date: Tue, 12 Nov 2019 06:29:56 GMT < Content-Type: text/html < Content-Length: 612 < Last-Modified: Wed, 26 Dec 2018 23:21:49 GMT < Connection: keep-alive < ETag: "5c240d0d-264" < Accept-Ranges: bytes < <style> body {<br /> width: 35em;<br /> margin: 0 auto;<br /> font-family: Tahoma, Verdana, Arial, sans-serif;<br /> }<br /> </style> <h1>Welcome to nginx!</h1> If you see this page, the nginx web server is successfully installed and working. Further configuration is required. For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>. Commercial support is available at <a href="http://nginx.com/">nginx.com</a>. <em>Thank you for using nginx.</em> * Connection #0 to host 10.1.21.66 left intact
CloudFormationテンプレート
実行タイミングについては、「ScheduleExpression: rate(1 day)」の部分を変更してください。cron形式でも記載できます。
sample-fargate-schedle.yaml
AWSTemplateFormatVersion: "2010-09-09" Description: Fargate and ALB Create Metadata: "AWS::CloudFormation::Interface": ParameterGroups: - Label: default: "Project Name Prefix" Parameters: - ProjectName - Label: default: "Fargate for ECS Configuration" Parameters: - ECSClusterName - ECSTaskName - ECSTaskCPUUnit - ECSTaskMemory - ECSContainerName - ECSImageName - ECSServiceName - ECSTaskDesiredCount - ECSScheduleRuleName - ECSScheduleTargetName ParameterLabels: ECSClusterName: default: "ECSClusterName" ECSTaskName: default: "ECSTaskName" ECSTaskCPUUnit: default: "ECSTaskCPUUnit" ECSTaskMemory: default: "ECSTaskMemory" ECSContainerName: default: "ECSContainerName" ECSImageName: default: "ECSImageName" ECSServiceName: default: "ECSServiceName" ECSTaskDesiredCount: default: "ECSTaskDesiredCount" # ------------------------------------------------------------# # Input Parameters # ------------------------------------------------------------# Parameters: ProjectName: Default: sample-fargate-batch Type: String #VPCID VpcId: Description : "VPC ID" Type: AWS::EC2::VPC::Id #ECSSecurity Group ECSSecurityGroupId: Type: AWS::EC2::SecurityGroup::Id #ECSSubnet1 ECSSubnetId1: Description : "ECS Subnet 1st" Type : AWS::EC2::Subnet::Id #ECSSubnet2 ECSSubnetId2: Description : "ECS Subnet 2st" Type : AWS::EC2::Subnet::Id #ECSClusterName ECSClusterName: Type: String Default: "cluster" #ECSTaskName ECSTaskName: Type: String Default: "task" #ECSTaskCPUUnit ECSTaskCPUUnit: AllowedValues: [ 256, 512, 1024, 2048, 4096 ] Type: String Default: "256" #ECSTaskMemory ECSTaskMemory: AllowedValues: [ 256, 512, 1024, 2048, 4096 ] Type: String Default: "512" #ECSContainerName ECSContainerName: Type: String Default: "container" #ECSImageName ECSImageName: Type: String Default: "xxxxxxxxxxxx.dkr.ecr.ap-northeast-1.amazonaws.com/kaji-test-ecr:latest" #ECSServiceName ECSServiceName: Type: String Default: "service" #ECSTaskDesiredCount ECSTaskDesiredCount: Type: Number Default: 1 #ECSScheduleRuleName ECSScheduleRuleName: Type: String Default: "batch-1day" #ECSScheduleTargetName ECSScheduleTargetName: Type: String Default: "target" Resources: # ------------------------------------------------------------# # ECS Cluster # ------------------------------------------------------------# ECSCluster: Type: "AWS::ECS::Cluster" Properties: ClusterName: !Sub "${ProjectName}-${ECSClusterName}" # ------------------------------------------------------------# # ECS LogGroup # ------------------------------------------------------------# ECSLogGroup: Type: "AWS::Logs::LogGroup" Properties: LogGroupName: !Sub "/ecs/logs/${ProjectName}-ecs-group" # ------------------------------------------------------------# # ECS Task Role IAM Policy # ------------------------------------------------------------# ECSTaskRoleIAMPolicy: Type: AWS::IAM::ManagedPolicy Properties: ManagedPolicyName: !Sub "${ProjectName}-ECSTaskPolicy" PolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Action: - sqs:SendMessage Resource: "*" # ------------------------------------------------------------# # ECS Task Role # ------------------------------------------------------------# ECSTaskRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${ProjectName}-ECSTaskRolePolicy" Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - !Ref ECSTaskRoleIAMPolicy # ------------------------------------------------------------# # ECS Task Execution Role # ------------------------------------------------------------# ECSTaskExecutionRole: Type: AWS::IAM::Role Properties: RoleName: !Sub "${ProjectName}-ECSTaskExecutionRolePolicy" Path: / AssumeRolePolicyDocument: Version: 2012-10-17 Statement: - Effect: Allow Principal: Service: ecs-tasks.amazonaws.com Action: sts:AssumeRole ManagedPolicyArns: - arn:aws:iam::aws:policy/service-role/AmazonECSTaskExecutionRolePolicy # ------------------------------------------------------------# # ECS TaskDefinition # ------------------------------------------------------------# ECSTaskDefinition: Type: "AWS::ECS::TaskDefinition" Properties: Cpu: !Ref ECSTaskCPUUnit ExecutionRoleArn: !Ref ECSTaskExecutionRole Family: !Sub "${ProjectName}-${ECSTaskName}" Memory: !Ref ECSTaskMemory NetworkMode: awsvpc TaskRoleArn: !Ref ECSTaskRole RequiresCompatibilities: - FARGATE #ContainerDefinitions ContainerDefinitions: - Name: !Sub "${ProjectName}-${ECSContainerName}" Image: !Ref ECSImageName LogConfiguration: LogDriver: awslogs Options: awslogs-group: !Ref ECSLogGroup awslogs-region: !Ref "AWS::Region" awslogs-stream-prefix: !Ref ProjectName MemoryReservation: 128 PortMappings: - HostPort: 80 Protocol: tcp ContainerPort: 80 # ------------------------------------------------------------# # ECS Events Rule # ------------------------------------------------------------# ECSSchedule: Type: AWS::Events::Rule Description: '' Properties: State: ENABLED ScheduleExpression: rate(1 day) Name: !Ref ECSScheduleRuleName Targets: - Id: !Sub "${ECSScheduleRuleName}-${ECSScheduleTargetName}" Arn: !GetAtt - ECSCluster - Arn RoleArn: !GetAtt - ECSTaskExecutionRole - Arn EcsParameters: TaskDefinitionArn: !Ref ECSTaskDefinition TaskCount: !Ref ECSTaskDesiredCount LaunchType: FARGATE NetworkConfiguration: AwsVpcConfiguration: AssignPublicIp: DISABLED SecurityGroups: - !Ref ECSSecurityGroupId Subnets: - !Ref ECSSubnetId1 - !Ref ECSSubnetId2